//
//  ViewController.m
//  ScreenRecord_ios_oc
//
//  Created by 51talk on 2021/5/11.
//

#import "ViewController.h"
#import "ScreenRecord.h"
//#import <UIKit/UIKit.h>
//#import <AVKit/AVKit.h>
//#import <AVFoundation/AVFoundation.h>
#import <ReplayKit/ReplayKit.h>
#import <CoreVideo/CoreVideo.h>

#import "NTESSocket.h"
#import "DumpFile.h"
#import "config.h"

static NSString *kAppGroup = @"group.screen.record.system";


@interface ViewController ()<MediaEngineDelegate,AudioDataCallbackDelegate,VideoProcessDataDelegate,SocketRecieve>
@property (weak, nonatomic) IBOutlet UITextField *userName;
@property (weak, nonatomic) IBOutlet UITextField *roomId;
@property (weak, nonatomic) IBOutlet UITextField *lbsAddr;
@property (weak, nonatomic) IBOutlet UITextField *sdk;
@property (weak, nonatomic) IBOutlet UIButton *login;
@property (weak, nonatomic) IBOutlet UIButton *logout;
@property (weak, nonatomic) IBOutlet UIView *localView;
@property (weak, nonatomic) IBOutlet UIView *remoteView1;
@property (weak, nonatomic) IBOutlet UIView *remoteView2;
@property (weak, nonatomic) IBOutlet UIView *remoteView3;
@property (weak, nonatomic) IBOutlet UIButton *openSpeaker;
@property (weak, nonatomic) IBOutlet UIButton *switchCamera;
@property (weak, nonatomic) IBOutlet UIButton *publishVideo;
@property (weak, nonatomic) IBOutlet UIButton *publishAudio;
@property (nonatomic, strong) RPSystemBroadcastPickerView *picker;

@property (nonatomic, strong) NSUserDefaults *userDefaults;
@property (nonatomic, strong) NTESSocket *serverSocket;

@property (nonatomic, strong) NSTimer *timer;


@end

@implementation ViewController
bool _isAudioPublish = false;
bool _isVideoPublish = false;
NSString *_remoteRenderUserId1 = @"";
NSString *_remoteRenderUserId2 = @"";
NSString *_remoteRenderUserId3 = @"";

bool enableScreenYuvWriteToFile = false;
bool flag = true;
DumpFile *dumpFile = nil;
ShareDataMode shareDataMode = AppGroups;

//通过 Socket 方案录制系统屏幕
int screenWidth = 886;
int screenHeight = 1918;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self initConfig];
    [self initUI];
    
    if(shareDataMode == AppGroups) {
        [self setupUserDefaults];
    } else if(shareDataMode == Socket) {
        [self setupServerSocket];
    }
    
    [self addSystemBroadcastPickerIfPossible];
//    NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//    NSLog(@"caches:%@",caches);
    
    [self setupTimer];

}

#pragma mark - 定时器
- (void)setupTimer {
    
    _timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerEvent:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
    [_timer fire];
}

- (void)timerEvent:(id)sender {
    
    NSLog(@"viewController 定时器运行中");
}

- (void)dealloc {
    [super dealloc];
    [self.userDefaults removeObserver:self forKeyPath:@"frame"];
    [self.userDefaults dealloc];
    self.userDefaults = nil;
}


- (void)initConfig {
    _userName.text = @"bruce123";
    _roomId.text = @"room147";
    _lbsAddr.text = @"172.19.134.56:8001";
    _sdk.text = @"8";
    //    _mediaEngineDelegate = self;
    _audioDataCallbackDelegate = self;
    _videoProcessDataDelegate = self;
}

-(void)initUI {
    [_openSpeaker setEnabled:false];
    [_switchCamera setEnabled:false];
    [_publishVideo setEnabled:false];
    [_publishAudio setEnabled:false];
}

-(void)initedUI {
    [_openSpeaker setEnabled:true];
    [_switchCamera setEnabled:true];
    [_publishVideo setEnabled:true];
    [_publishAudio setEnabled:true];
}

- (void)loginedUI {
    [self initedUI];
    [_openSpeaker setTitle:@"关闭扬声器" forState:UIControlStateNormal];
    [_publishVideo setTitle:@"取消发布视频" forState:UIControlStateNormal];
    [_publishAudio setTitle:@"取消发布音频" forState:UIControlStateNormal];
    _isAudioPublish = true;
    _isVideoPublish = true;
}

- (void)logoutUI {
    [self initUI];
    [_openSpeaker setTitle:@"打开扬声器" forState:UIControlStateNormal];
    [_publishVideo setTitle:@"发布视频" forState:UIControlStateNormal];
    [_publishAudio setTitle:@"发布音频" forState:UIControlStateNormal];
    _isAudioPublish = false;
    _isVideoPublish = false;
}

- (void) OnEngineEvent:(EngineEvent*)ev {
    if ([[ev EventName] isEqualToString:[EngineSessionStateEvent TypeName]]) {
        int newState = (int)[(EngineSessionStateEvent*)ev getNewState];
        if(newState == SESSION_STATE_ENTERED) {
            if(_isAudioPublish) {
                [[MediaEngine SDK] OpenMic];
                [[MediaEngine SDK] SetLoudSpeakerStatus:YES];
                [[MediaEngine SDK] EnableVoiceLevelEvent:YES];
                [[MediaEngine SDK] EnableAudioEvent:YES];
                [[MediaEngine SDK] EnableRenderEvent:YES];
                [[MediaEngine SDK] EnableSpeedMonitor:YES];
            }
            
            if(_isVideoPublish) {
                [[MediaEngine SDK] StopPreview];
                
                DeviceInfoArray* deviceInfoArray = [DeviceInfoArray new];
                [[MediaEngine SDK] GetCameraDevices:deviceInfoArray];
                
                if (deviceInfoArray.size >= 2)
                {
                    //0是后置摄像头，1是前置摄像头
                    [[MediaEngine SDK] SetCameraDevice:1];
                }
                
                //发布自己的视频
                [[MediaEngine SDK] OpenCamera];
                [[MediaEngine SDK] StartPreview:_localView];
            }
        } else if(newState == SESSION_STATE_LEAVE || newState == SESSION_STATE_ERROR) {
            [[MediaEngine SDK] EnableAudioEvent:NO];
            [[MediaEngine SDK] EnableRenderEvent:NO];
            [[MediaEngine SDK] EnableSpeedMonitor:NO];
            [[MediaEngine SDK] EnableVoiceLevelEvent:NO];
        }
    } else if([[ev EventName] isEqualToString:[EngineInitializeEvent TypeName]]) {
        EngineInitializeEvent *eve = (EngineInitializeEvent*)ev;
        if ([eve getCode] == 0) {
            SessionSettingArray *settings = [SessionSettingArray new];
            Setting *sdkSwitch = [Setting new];
            [sdkSwitch setKey:@"enableSwitchSdk"];
            [sdkSwitch setValue:@"1"];
            [settings add:sdkSwitch];
            Setting *screenRecord = [Setting new];
            [screenRecord setKey:@"capture"];
            [screenRecord setValue:@"1"];
            [settings add:screenRecord];
            [[MediaEngine SDK] EnterSession:_roomId.text settings:settings];
        }
    } else if([[ev EventName] isEqualToString:[EngineMediaPublishStatusEvent TypeName]]) {
        NSLog(@"recieved engine event：%@,userid:%@", [ev EventName], [ev getUserId]);
        
        EngineMediaPublishStatusEvent *eve = (EngineMediaPublishStatusEvent *)ev;
        if([[eve getUserId] isEqualToString:_userName.text]) {
            return;
        }
        
        //收到远端视频发布
        if([eve getType] == MediaType_Video) {
            //发布视频
            if([eve getAction] == MediaPublishStatusStart) {
                [[MediaEngine SDK] EnableVideoProcessCallback:[eve getUserId] enable:YES type:kI420];
                if([_remoteRenderUserId1 isEqualToString:@""]) {
                    [[MediaEngine SDK] StartRender:[eve getUserId] view:_remoteView1];
                    _remoteRenderUserId1 = [eve getUserId];
                } else {
                    NSLog(@"there is no more view to render remote video!");
                }
            }
            //取消发布视频
            else if([eve getAction] == MediaPublishStatusStop) {
                [[MediaEngine SDK] EnableVideoProcessCallback:[eve getUserId] enable:NO type:kI420];
                [[MediaEngine SDK] StopRender:[eve getUserId]];
                if([[eve getUserId] isEqualToString:_remoteRenderUserId1]) {
                    _remoteRenderUserId1 = @"";
                }
            }
        } else if ([eve getType] == MediaType_Screen) {
            NSLog(@"远端共享流");
            //远端发布共享流
            if([eve getAction] == MediaPublishStatusStart) {
                [[MediaEngine SDK] EnableVideoProcessCallback:[eve getUserId] enable:YES type:kI420];
                
                if([_remoteRenderUserId2 isEqualToString:@""]) {
                    NSLog(@"开始渲染共享流：userid=%@", [eve getUserId]);
                    [[MediaEngine SDK] StartRenderScreen:[eve getUserId] view:_remoteView2];
                    _remoteRenderUserId2 = [eve getUserId];
                }
            }
            //取消发布视频
            else if([eve getAction] == MediaPublishStatusStop) {
                [[MediaEngine SDK] EnableVideoProcessCallback:[eve getUserId] enable:NO type:kI420];
                
                if([[eve getUserId] isEqualToString:_remoteRenderUserId2]) {
                    _remoteRenderUserId2 = @"";
                    [[MediaEngine SDK] StopRenderScreen:[eve getUserId]];
                    
                }
            }
        }
    }
}

-(void)OnAudioDataCallbackProcess:(AudioCallbackData*)audiodata {
    //    NSLog(@"OnAudioDataCallbackProcess");
}

-(void) onCaptureVideoFrame: (unsigned char *)frame length: (int)length width: (int)width height: (int)height {
    //    NSLog(@"onCaptureVideoFrame");
}

-(void) onRenderVideoFrame: (NSString*)userId frame: (unsigned char *)frame length: (int)length width: (int)width height: (int)height {
    //    NSLog(@"onRenderVideoFrame");
}

- (void)initMediaEngin {
    EngineEventListenerObjc *engineEventListenerObjc = [EngineEventListenerObjc Instance];
    [engineEventListenerObjc setDelegate:self];
    [MediaEngine Init:(EngineEventListener *)engineEventListenerObjc];
    [MediaEngine UseSdk:(unsigned char)[_sdk.text intValue]];
    
    NSString *documentPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;
    NSString *  trace = [documentPath stringByAppendingString:@"/acme.log"];
    //    NSLog(@"%@", trace);
    EngineConfig *engineConfig = [EngineConfig new];
    [engineConfig setTrace:trace];
    [engineConfig setUserId:_userName.text];
    [engineConfig setLbs:_lbsAddr.text];
    
    ////        let tokenArray = UInt8Array()
    ////        tokenArray?.add(0)
    ////        engineConfig?.setToken(tokenArray)
    [MediaEngine InitializeSdk:engineConfig];
    //
    MediaEngine *mediaEngine = [MediaEngine SDK];
    
    //    //add by wuzhaoyang
    int type = kRecordingPreprocessing;
    AudioDataCallbackObjc *audioDataCallback = [AudioDataCallbackObjc Instance];
    [audioDataCallback setDelegate:self];
    VideoProcessCallbackDataObjc * videoProcessCallback = [VideoProcessCallbackDataObjc Instance];
    videoProcessCallback.delegate = self;
    
    [mediaEngine EnableAudioDataCallback:true processingtype:type callback:(EngineAudioDataCallback *)audioDataCallback];
    [mediaEngine RegisterVideoProcessCallback:videoProcessCallback ];
    [mediaEngine EnableVideoProcessCallback:_userName.text enable: true type: kI420];
}

- (void)deInitMediaEngin {
    AudioDataCallbackObjc *audioDataCallback = [AudioDataCallbackObjc Instance];
    [audioDataCallback setDelegate:_audioDataCallbackDelegate];
    int type = kRecordingPreprocessing;
    MediaEngine *mediaEngine = [MediaEngine SDK];
    [mediaEngine EnableAudioDataCallback:false processingtype:type callback:[AudioDataCallbackObjc Instance]];
    [VideoProcessCallbackDataObjc Instance].delegate = nil;
    [mediaEngine EnableVideoProcessCallback:_userName.text enable:false type:kI420];
    // fclose(fp)
    
    [mediaEngine StopPreview];
    [mediaEngine CloseCamera];
    [mediaEngine LeaveSession];
    [MediaEngine TerminateSdk];
    [MediaEngine UnInit];
}

- (void)setupServerSocket
{
    NSLog(@"创建服务器socket，并等待客户端连接");
    self.serverSocket = [[NTESSocket alloc] initWithPort:@"8898" ip:@"127.0.0.1"];
    // 收到的数据通过 Delegate 接收
    [self.serverSocket setDelegate:self];
    // 开始接受客户端的连接请求
    [self.serverSocket startAcceptClient];
}

- (void)onRecvData:(uint8_t *)data len:(int)length
{
    // SDK自定义视频数据发送接口
    [[MediaEngine SDK] DeliverExternalFrame:kI420 frame:data width:screenWidth height:screenHeight size:length];
    if(enableScreenYuvWriteToFile && flag) {
        dumpFile = [[DumpFile alloc] init];
        [dumpFile openFileStream:screenWidth height:screenHeight];
        flag = false;
    }
    
    if(dumpFile != nil) {
        [dumpFile writeToFile:data size:length];
    }
}

- (void)setupUserDefaults
{
    // 通过UserDefaults建立数据通道，接收Extension传递来的视频帧
    self.userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kAppGroup];
    [self.userDefaults addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
//    [self.userDefaults addObserver:self forKeyPath:@"bruce" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    static int num = 0;
    num++;
    if(num%50 == 0) {
        NSLog(@"observeValueForKeyPath");
    }
    if ([keyPath isEqualToString:@"frame"]) {
        NSDictionary *i420Frame = change[NSKeyValueChangeNewKey];
        int width = [i420Frame[@"width"] unsignedIntValue];
        int height = [i420Frame[@"height"] unsignedIntValue];
        if(num%50 == 0) {
            NSLog(@"width:%d, height:%d", width, height);
        }
        void* buffer = (void *)[i420Frame[@"data"] bytes];
        [[MediaEngine SDK] DeliverExternalFrame:kI420 frame:(unsigned char*)buffer width:width height:height size:width*height*3/2];
    }
//    else if([keyPath isEqualToString:@"bruce"]) {
//        NSDictionary *tmp = change[NSKeyValueChangeNewKey];
//        NSString *str = tmp[@"bruce"];
//        if(num%50 == 0) {
//            NSLog(@"str:%@", str);
//        }
//    }
}

- (void)addSystemBroadcastPickerIfPossible
{
    if (@available(iOS 12.0, *)) {
        NSLog(@"当前系统版本大于等于12.0");
        _picker = [[RPSystemBroadcastPickerView alloc] initWithFrame:CGRectMake(0, 0, 140, 40)];
        _picker.showsMicrophoneButton = NO;
        _picker.preferredExtension = @"-1talk.ScreenRecord-ios-oc.ScreenRecordUpload";
        [self.view addSubview:_picker];
        _picker.center = self.view.center;
        
        UIButton *button = [_picker.subviews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
            return [evaluatedObject isKindOfClass:UIButton.class];
        }]].firstObject;
        [button setImage:nil forState:UIControlStateNormal];
        [button setTitle:@"启动系统屏幕录制" forState:UIControlStateNormal];
        [button setTitleColor:self.navigationController.navigationBar.tintColor forState:UIControlStateNormal];
        button.backgroundColor = [UIColor blueColor];
//        button.hidden = true;
        [button addTarget:self action:@selector(openSystemScreenRecord:) forControlEvents:UIControlEventTouchUpInside];
        
//        UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView:_picker];
//        self.navigationItem.leftBarButtonItem = leftItem;
    }
}

- (IBAction)startSystemScreenRecord:(UIButton *)sender {
    if([sender.titleLabel.text isEqualToString:@"启动系统屏幕录制"]) {
        NSLog(@"启动系统屏幕录制");
        [[MediaEngine SDK] OpenExternalCapture];
        [sender setTitle:@"关闭系统屏幕录制" forState:UIControlStateNormal];
    } else if([sender.titleLabel.text isEqualToString:@"关闭系统屏幕录制"]){
        NSLog(@"关闭系统屏幕录制");
        [[MediaEngine SDK] CloseExternalCapture];
        [sender setTitle:@"启动系统屏幕录制" forState:UIControlStateNormal];
    }
    
//    for (UIView *view in _picker.subviews)
//    {
//        if ([view isKindOfClass:[UIButton class]])
//        {
//            [(UIButton*)view sendActionsForControlEvents:UIControlEventAllTouchEvents];
//        }
//    }
}

-(void)openSystemScreenRecord:(UIButton*)button {
    if([button.titleLabel.text isEqualToString:@"启动系统屏幕录制"]) {
        NSLog(@"启动系统屏幕录制");
        [[MediaEngine SDK] OpenExternalCapture];
        [button setTitle:@"关闭系统屏幕录制" forState:UIControlStateNormal];
    } else if([button.titleLabel.text isEqualToString:@"关闭系统屏幕录制"]){
        NSLog(@"关闭系统屏幕录制");
        [[MediaEngine SDK] CloseExternalCapture];
        [button setTitle:@"启动系统屏幕录制" forState:UIControlStateNormal];
    }
}

- (IBAction)onLogin:(UIButton*)sender {
    [self loginedUI];
    [self initMediaEngin];
}

- (IBAction)onLogout:(UIButton *)sender {
    [self deInitMediaEngin];
    [self logoutUI];
}

- (IBAction)openSpeaker:(UIButton *)sender {
    if([sender.titleLabel.text isEqualToString:@"关闭扬声器"]) {
        NSLog(@"关闭扬声器");
        [[MediaEngine SDK] SetLoudSpeakerStatus:false];
        [sender setTitle:@"打开扬声器" forState:UIControlStateNormal];
    } else if([sender.titleLabel.text isEqualToString:@"打开扬声器"]) {
        NSLog(@"打开扬声器");
        [[MediaEngine SDK] SetLoudSpeakerStatus:true];
        [sender setTitle:@"关闭扬声器" forState:UIControlStateNormal];
    }
}

- (IBAction)switchCamera:(UIButton *)sender {
    NSLog(@"切换摄像头");
//    if _cameraSwitch.isOn {
//        MediaEngine.sdk().setCameraDevice(1)
//    }
//    else{
//        MediaEngine.sdk().setCameraDevice(0)
//    }
}

- (IBAction)publishAudio:(UIButton *)sender {
    if([sender.titleLabel.text isEqualToString: @"取消发布音频"]) {
        NSLog(@"取消发布音频");
        [[MediaEngine SDK] CloseMic];
        [sender setTitle:@"发布音频" forState:UIControlStateNormal];
    } else if([sender.titleLabel.text isEqualToString: @"发布音频"]) {
        NSLog(@"发布音频");
        [[MediaEngine SDK] OpenMic];
        [sender setTitle:@"取消发布音频" forState:UIControlStateNormal];
    }
}

- (IBAction)publishVideo:(UIButton *)sender {
    if([sender.titleLabel.text isEqualToString:@"取消发布视频"]) {
        NSLog(@"取消发布视频");
        [[MediaEngine SDK] StopPreview];
        [[MediaEngine SDK] CloseCamera];
        [sender setTitle:@"发布视频" forState:UIControlStateNormal];
    } else if([sender.titleLabel.text isEqualToString:@"发布视频"]) {
        NSLog(@"发布视频");
        DeviceInfoArray* deviceInfoArray = [DeviceInfoArray new];
        [[MediaEngine SDK] GetCameraDevices:deviceInfoArray];
        if (deviceInfoArray.size >= 2)
        {
            //0是后置摄像头，1是前置摄像头
            [[MediaEngine SDK] SetCameraDevice:1];
        }
        
        //发布自己的视频
        [[MediaEngine SDK] OpenCamera];
        [[MediaEngine SDK] StartPreview:_localView];
        [sender setTitle:@"取消发布视频" forState:UIControlStateNormal];
    }
}

- (IBAction)startScreenRecord:(UIButton *)sender {
    if (@available(iOS 11.0, *)) {
        sender.enabled = NO;
        if ([sender.titleLabel.text isEqualToString:@"开启应用内录屏"]) {
            if ([RPScreenRecorder sharedRecorder].isRecording) {
                sender.enabled = YES;
                NSLog(@"isRecording");
                return;
            }
            NSLog(@"startScreenRecord");
            [[MediaEngine SDK] OpenExternalCapture];
            
            // 是否开启麦克风
            [[RPScreenRecorder sharedRecorder] setMicrophoneEnabled:YES];
            [[RPScreenRecorder sharedRecorder] startCaptureWithHandler:^(CMSampleBufferRef  _Nonnull sampleBuffer, RPSampleBufferType bufferType, NSError * _Nullable error) {
                //                NSLog(@"startCaptureWithHandler error = %@", error);
                [[ScreenRecord getInstance] handleSampleBuffer:bufferType sampleBufferRef:sampleBuffer];
                
            } completionHandler:^(NSError * _Nullable error) {
                NSLog(@"completionHandler error = %@", error);
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (error == nil) {
                        [sender setTitle:@"关闭应用内录屏" forState:UIControlStateNormal];
                    } else {
                        [[MediaEngine SDK] CloseExternalCapture];
                    }
                    sender.enabled = YES;
                });
            }];
            
        } else if ([sender.titleLabel.text isEqualToString:@"关闭应用内录屏"]) {
            
            if (![RPScreenRecorder sharedRecorder].isRecording) {
                sender.enabled = YES;
                return;
            }
            NSLog(@"stopScreenRecord");
            
            [[RPScreenRecorder sharedRecorder] stopCaptureWithHandler:^(NSError * _Nullable error) {
                NSLog(@"stopCaptureWithHandler error = %@", error);
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (error == nil) {
                        [[MediaEngine SDK] CloseExternalCapture];
                        [sender setTitle:@"开启应用内录屏" forState:UIControlStateNormal];
                    }
                    sender.enabled = YES;
                });
            }];
        }
        
    } else {
        [self showAlertWithMessage:@"您的系统低于iOS 11，请升级。"];
    }
}


#pragma mark - private

- (void)showAlertWithMessage:(NSString *)message {
    UIAlertController * alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:message preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * ok = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleCancel handler:nil];
    [alertController addAction:ok];
    [self presentViewController:alertController animated:YES completion:nil];
}

@end
